#include "lcd_src_manager.h"
#include "ugui.h"
#include "string.h"
#include "W25Qxx.h" // 添加W25Q函数声明
#include "stdio.h"  // 添加printf函数声明



struct src_head_t src_head;
struct src_addr_item_t src_addr_top_item_table[10];
struct src_addr_item_t src_addr_table;  // 改为单个结构体，只存储当前需要的资源项
tImage g_image_buffer;    // 用作图片缓冲区
tFont  g_font_buffer;     // 用作字体缓冲区


#define SRC_MANAGER_DEBUG 1
#define STATIC_LINE_BUF_SIZE 2048

#if SRC_MANAGER_DEBUG
#define src_log printf
#else
#define src_log(...)
#endif

// 新增：按需读取指定索引的地址表项
static uint8_t src_manager_read_addr_table_item(uint32_t index);
// 新增：按名称查找并读取地址表项
static uint8_t src_manager_find_and_read_by_name(char *name, enum is_type_e type, struct src_addr_item_t *item);
// 新增：按父ID和字符编码查找并读取地址表项
static uint8_t src_manager_find_and_read_font_char(uint32_t parent_id, uint32_t char_code, struct src_addr_item_t *item);

static struct src_addr_item_t addr_table_find_name(char *name,enum is_type_e type);       // 按照名称查顶层资源
static struct src_addr_item_t addr_tanle_find_font_code(char *name);                      // 按照带编号的名称查字符的索引          
void src_manager_print_image_by_lines( uint16_t x, uint16_t y, tImage image, uint32_t addr); // 指定每次显示的行数 分多次显示 节省空间
uint8_t _OLED_GetUTF8Len(char *string);

// 新增：RGB565 字节序可选交换（当生成端与MCU端字节序不一致时使能）
#ifndef LCD_SRC_RGB565_SWAP_BYTES
#define LCD_SRC_RGB565_SWAP_BYTES 0
#endif

static inline void swap_rgb565_bytes(uint8_t *buf, uint32_t len)
{
#if LCD_SRC_RGB565_SWAP_BYTES
	for (uint32_t i = 0; i + 1 < len; i += 2)
	{
		uint8_t t = buf[i];
		buf[i] = buf[i + 1];
		buf[i + 1] = t;
	}
#else
	(void)buf; (void)len;
#endif
}

// 新增：计算数据区内资源的绝对地址（叠加 data_area_base_addr）
static inline uint32_t src_get_real_data_addr(uint32_t offset)
{
	return src_head.data_area_base_addr + offset;
}

// 新增：安全的跨页读取，内部按页读取并复制所需数据
static void flash_read_cross_pages(uint32_t abs_addr, uint32_t size, uint8_t *dst)
{
	uint32_t remain = size;
	uint32_t addr = abs_addr;
	uint8_t *p = dst;
	uint8_t page_buf[256];

	while (remain > 0)
	{
		uint32_t page = addr / 256;
		uint32_t page_offset = addr % 256;
		uint32_t chunk = 256 - page_offset;
		if (chunk > remain) chunk = remain;

		W25Q_Read(page, (uint8_t)page_offset, chunk, page_buf);
		memcpy(p, page_buf, chunk);

		addr += chunk;
		p += chunk;
		remain -= chunk;
	}
}

uint8_t src_manager_read_head(void){
	// 读取资源头部信息到src_head结构体
	W25Q_Read(0, 0, sizeof(struct src_head_t), (uint8_t *)&src_head);

	src_head.addr_table_item_count = src_head.reserved[0];

	return 0;
}

// 新增：按需读取指定索引的地址表项
static uint8_t src_manager_read_addr_table_item(uint32_t index)
{
	if (index >= src_head.addr_table_item_count) {
		src_log("错误：索引超出范围: %lu >= %lu\r\n", index, src_head.addr_table_item_count);
		return 1;
	}
	
	// 计算地址表项在Flash中的位置
	uint32_t addr = src_head.addr_table_addr + index * sizeof(struct src_addr_item_t);
	uint32_t page = addr / 256;
	uint32_t offset = addr % 256;
	
	// 检查是否需要跨页读取
	uint32_t struct_size = sizeof(struct src_addr_item_t);
	if (offset + struct_size > 256) {
		// 需要跨页读取，使用跨页读取函数
		flash_read_cross_pages(addr, struct_size, (uint8_t *)&src_addr_table);
		src_log("跨页读取地址表项[%lu]: addr=0x%08lX, page=%lu, offset=%lu\r\n", 
				index, addr, page, offset);
	} else {
		// 单页内读取
		W25Q_Read(page, (uint8_t)offset, struct_size, (uint8_t *)&src_addr_table);
		src_log("单页读取地址表项[%lu]: addr=0x%08lX, page=%lu, offset=%lu\r\n", 
				index, addr, page, offset);
	}
	
	// 验证读取的数据完整性
	if (src_addr_table.id == 0 && src_addr_table.type == 0) {
		src_log("警告：读取的地址表项数据可能无效，id=%lu, type=%u\r\n", 
				src_addr_table.id, src_addr_table.type);
	}
	
	// 输出调试信息
	src_log("地址表项[%lu]: id=%lu, name='%s', type=%u, size=%lu\r\n", 
			index, src_addr_table.id, src_addr_table.name, src_addr_table.type, src_addr_table.size);
	
	return 0;
}

// 按名称查找并读取地址表项
static uint8_t src_manager_find_and_read_by_name(char *name, enum is_type_e type, struct src_addr_item_t *item)
{
	if (name == NULL || item == NULL) {
		return 1;
	}
	
	// 直接遍历只读地址表，查找顶层资源
	const size_t count = sizeof(g_addr_table) / sizeof(g_addr_table[0]);
	for (size_t i = 0; i < count; i++) {
		const struct src_addr_item_t *p = &g_addr_table[i];
		if (p->parent_id != 0) continue; // 顶层
		if (p->type != type) continue;   // 类型
		if (strcmp(p->name, name) != 0) continue; // 名称
		memcpy(item, p, sizeof(struct src_addr_item_t));
		return 0;
	}
	return 1;
}

// 新增：按父ID和字符编码查找并读取地址表项
static uint8_t src_manager_find_and_read_font_char(uint32_t parent_id, uint32_t char_code, struct src_addr_item_t *item)
{
	if (item == NULL) {
		return 1;
	}
	
	// 直接遍历只读地址表，查找字体字符
	const size_t count = sizeof(g_addr_table) / sizeof(g_addr_table[0]);
	for (size_t i = 0; i < count; i++) {
		const struct src_addr_item_t *p = &g_addr_table[i];
		if (p->type != is_font_char) continue;
		if (p->parent_id != parent_id) continue;
		if (p->char_code != char_code) continue;
		memcpy(item, p, sizeof(struct src_addr_item_t));
		return 0;
	}
	return 1;
}

uint8_t src_manager_read_addr_table(){
    // 遍历g_addr_table数组，输出每个资源项的基本信息
    static uint8_t top_src_num = 0;
    size_t count = sizeof(g_addr_table) / sizeof(g_addr_table[0]);
    for (size_t i = 0; i < count; i++) {
        const struct src_addr_item_t *p = &g_addr_table[i]; 
        if (p->parent_id == 0)
        {
            if(top_src_num == 10){
                src_log("Top-level resource count exceeds 10, stopping.\r\n");
                return 1;            // 顶层资源，最多只处理10个，超过则提前返回
            }
            // 将顶层资源赋值到 src_addr_top_item_table 数组中
            memcpy(&src_addr_top_item_table[top_src_num], p, sizeof(struct src_addr_item_t));
            top_src_num++;
        }
    }
    return 0;
}

// 构建图片显示功能
uint8_t src_manager_show_image(uint16_t x, uint16_t y, char *name){
	struct src_addr_item_t item;
	uint32_t image_addr = 0;
	uint16_t width = 0, height = 0;
	uint8_t dataSize = 0;
	uint32_t size = 0;

	// 查找并读取图片资源
	if (src_manager_find_and_read_by_name(name, is_image, &item) != 0) {
		src_log("未找到图片资源: %s\r\n", name);
		return 0;
	}

	image_addr = item.offset;
	width = item.width;
	height = item.height;
	dataSize = item.dataSize;
	size = item.size;

	// 读取图片数据到g_image_buffer
	g_image_buffer.width = width;
	g_image_buffer.height = height;
	g_image_buffer.dataSize = dataSize;
	g_image_buffer.data = NULL;

	src_manager_print_image_by_lines(x, y, g_image_buffer, image_addr);

	return 1;
}

uint8_t src_manager_show_font_char(uint16_t x, uint16_t y, char *name, uint32_t code){
	struct src_addr_item_t font_item;
	struct src_addr_item_t char_item;
	uint8_t found = 0;

	// 1. 先查找父节点（字体资源）
	if (src_manager_find_and_read_by_name(name, is_font, &font_item) != 0) {
		src_log("未找到字体资源: %s\r\n", name);
		return 0;
	}

	// 2. 查找并读取字体字符节点
	if (src_manager_find_and_read_font_char(font_item.id, code, &char_item) == 0) {
		// 找到后，构造tImage结构体
		tImage char_image;
		char_image.width = char_item.width;
		char_image.height = char_item.height;
		char_image.dataSize = char_item.dataSize;
		char_image.data = NULL; // 数据从Flash读取

		// 按行显示该字符图像
		src_manager_print_image_by_lines(x, y, char_image, char_item.offset);
		found = 1;
	}

	if(!found) {
		src_log("未找到字体字符: %s, code: 0x%08X\r\n", name, code);
		return 0;
	}

	return 1;
}


// 参考 OLED_PrintString 的实现，自动识别 ASCII 和 UTF-8 字符
uint8_t src_manager_show_String(uint16_t x, uint16_t y,const char *string, char *name)
{
    uint16_t curr_x = x;
    uint16_t curr_y = y;
    uint8_t ret = 1;
    uint32_t code;
    uint16_t char_width = 0;
    uint16_t char_height = 0;

    // 1. 查找字体资源，获取字符高度
    struct src_addr_item_t font_item;
    if (src_manager_find_and_read_by_name(name, is_font, &font_item) != 0) {
        src_log("未找到字体资源: %s\r\n", name);
        return 0;
    }
    char_height = font_item.height;

    // 2. 遍历字符串，自动识别 ASCII/UTF-8
    uint8_t *p = (uint8_t *)string;
    while(*p)
    {
        uint8_t utf8Len = 0;
        // 判断 UTF-8 长度
        if((*p & 0x80) == 0x00) {
            utf8Len = 1;
        } else if((*p & 0xE0) == 0xC0) {
            utf8Len = 2;
        } else if((*p & 0xF0) == 0xE0) {
            utf8Len = 3;
        } else if((*p & 0xF8) == 0xF0) {
            utf8Len = 4;
        } else {
            utf8Len = 1; // 错误编码，跳过
        }

        // 只支持 ASCII 和常见中文（3字节UTF-8）
        if(utf8Len == 1) // ASCII
        {
            code = *p;
            if(!src_manager_show_font_char(curr_x, curr_y, name, code)) {
                ret = 0;
            }
            // 查找字符具体宽度
            struct src_addr_item_t char_item;
            if (src_manager_find_and_read_font_char(font_item.id, code, &char_item) == 0) {
                char_width = char_item.width;
            } else {
                char_width = font_item.width; // 未找到则用默认宽度
            }
            curr_x += char_width;
            p += 1;
        }
        else if(utf8Len == 3) // 中文UTF-8三字节
        {
            code = ((uint32_t)p[0] << 16) | ((uint32_t)p[1] << 8) | p[2];
            if(!src_manager_show_font_char(curr_x, curr_y, name, code)) {
                ret = 0;
            }
            // 必须使用具体的字符宽度
            struct src_addr_item_t char_item;
            if (src_manager_find_and_read_font_char(font_item.id, code, &char_item) == 0) {
                char_width = char_item.width;
            } else {
                char_width = font_item.width; // 未找到则用默认宽度
            }
            curr_x += char_width;
            p += 3;
        }
        else // 其他 UTF-8 长度（如2字节、4字节等），暂不支持，显示空格
        {
            // 可以选择显示空格或直接跳过
            char_width = font_item.width;
            curr_x += char_width;
            p += utf8Len;
        }
    }
    return ret;
}





// 批量显示字符编号数组（支持中文/ASCII混合）
// codes: 字符编号数组
// count: 数组长度
// x, y: 起始坐标
// name_en: 英文字体资源名
// name_cn: 中文字体资源名
// 返回值：成功返回1，失败返回0
uint8_t src_manager_show_code_array(uint16_t x, uint16_t y, const uint32_t *codes, uint16_t count, char *name_en, char *name_cn)
{
    if (!codes || count == 0) return 0;
    uint16_t curr_x = x;
    uint16_t curr_y = y;
    uint8_t ret = 1;

    // 查找英文字体资源，获取默认宽度
    struct src_addr_item_t font_item_en;
    if (src_manager_find_and_read_by_name(name_en, is_font, &font_item_en) != 0) {
        src_log("未找到英文字体资源: %s\r\n", name_en);
        return 0;
    }
    // 查找中文字体资源，获取默认宽度
    struct src_addr_item_t font_item_cn;
    if (src_manager_find_and_read_by_name(name_cn, is_font, &font_item_cn) != 0) {
        src_log("未找到中文字体资源: %s\r\n", name_cn);
        return 0;
    }

    for (uint16_t i = 0; i < count; i++) {
        uint32_t code = codes[i];
        uint16_t char_width = 0;
        char *use_font_name = NULL;
        struct src_addr_item_t *use_font_item = NULL;

        // 判断是英文字符还是中文字符
        if (code < 0x80) { // ASCII 英文
            use_font_name = name_en;
            use_font_item = &font_item_en;
            char_width = font_item_en.width;
        } else { // 中文或其他
            use_font_name = name_cn;
            use_font_item = &font_item_cn;
            char_width = font_item_cn.width;
        }

        // 显示字符
        if (!src_manager_show_font_char(curr_x, curr_y, use_font_name, code)) {
            ret = 0;
        }

        // 查找具体宽度
        struct src_addr_item_t char_item;
        if (src_manager_find_and_read_font_char(use_font_item->id, code, &char_item) == 0) {
            char_width = char_item.width;
        }
        curr_x += char_width;
    }
    return ret;
}



// 新增：字符宽度快速查找表结构体
typedef struct {
    uint32_t char_code;
    uint16_t width;
} char_width_entry_t;

// 新增：通过tFont结构体快速查找字符宽度
static uint16_t get_char_width_from_font(const tFont* font, uint32_t char_code)
{
    if (!font || !font->chars) return 0;
    
    // 对于ASCII字符（0-127），使用快速查找表
    if (char_code < 128) {
        // 创建快速查找表（仅对当前字体）
        static char_width_entry_t quick_table[128];
        static const tFont* last_font = NULL;
        static uint8_t table_initialized = 0;
        
        // 如果字体发生变化，重新初始化查找表
        if (last_font != font || !table_initialized) {
            // 清空查找表
            memset(quick_table, 0, sizeof(quick_table));
            
            // 填充查找表
            for (int i = 0; i < font->length; i++) {
                if (font->chars[i].code < 128) {
                    quick_table[font->chars[i].code].char_code = font->chars[i].code;
                    quick_table[font->chars[i].code].width = font->chars[i].image->width;
                }
            }
            
            last_font = font;
            table_initialized = 1;
        }
        
        // 直接查找
        if (quick_table[char_code].char_code == char_code) {
            return quick_table[char_code].width;
        }
    }
    
    // 对于非ASCII字符或查找表未命中，使用线性查找
    for (int i = 0; i < font->length; i++) {
        if (font->chars[i].code == char_code) {
            return font->chars[i].image->width;
        }
    }
    
    return 0; // 未找到
}


static uint32_t get_font_by_name(const char* name)
{
    if (!name) return 0;

    // 遍历顶层资源表，查找类型为 is_font 的资源
    for (int i = 0; i < 10; i++) {
        if (src_addr_top_item_table[i].type != is_font) continue;
        if (strcmp(src_addr_top_item_table[i].name, name) == 0) {
            return src_addr_top_item_table[i].id;
        }
    }

    return 0; // 未找到
}

/**
 * @brief 计算英文字符串的总宽度（按具体字符宽度累加，优化：仅遍历一遍字库地址表，每次批量比较多个字符）
 * @param name 字体资源名称
 * @param string 需要计算宽度的英文字符串
 * @return 字符串总宽度（像素）
 *
 * 优化说明：先将字符串解析为字符编码数组，然后仅遍历一遍字库地址表，批量比较所有字符编码，极大提升效率。
 */
uint8_t src_manager_get_en_string_lenght(char *name, const char *string)
{
    if (!string || !*string || !name) return 0;

    // 1. 查找字体资源
    struct src_addr_item_t font_item = {0};
    int found = 0;
    for (int i = 0; i < 10; i++) {
        if (src_addr_top_item_table[i].type == is_font && strcmp(src_addr_top_item_table[i].name, name) == 0) {
            font_item = src_addr_top_item_table[i];
            found = 1;
            break;
        }
    }
    if (!found) {
        src_log("未找到字体: %s\r\n", name);
        return 0;
    }

    // 2. 解析字符串为字符编码数组
    #define MAX_STRING_CHAR_NUM 32
    uint32_t char_codes[MAX_STRING_CHAR_NUM] = {0};
    uint8_t char_widths[MAX_STRING_CHAR_NUM] = {0}; // 记录宽度
    uint8_t char_found[MAX_STRING_CHAR_NUM] = {0};  // 标记是否找到
    uint8_t char_num = 0;
    const uint8_t *p = (const uint8_t *)string;
    while (*p && char_num < MAX_STRING_CHAR_NUM) {
        uint8_t utf8Len = 0;
        uint32_t char_code = 0;
        if ((*p & 0x80) == 0x00) {
            utf8Len = 1;
            char_code = *p;
        } else if ((*p & 0xE0) == 0xC0) {
            utf8Len = 2;
            char_code = ((uint32_t)p[0] << 8) | p[1];
        } else if ((*p & 0xF0) == 0xE0) {
            utf8Len = 3;
            char_code = ((uint32_t)p[0] << 16) | ((uint32_t)p[1] << 8) | p[2];
        } else if ((*p & 0xF8) == 0xF0) {
            utf8Len = 4;
            char_code = ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | p[3];
        } else {
            utf8Len = 1;
            char_code = *p;
        }
        char_codes[char_num++] = char_code;
        p += utf8Len;
    }

    // 3. 仅遍历一遍字库地址表，批量比较所有字符编码
    uint32_t font_char_start_index = font_item.id;
    uint16_t char_count = font_item.char_count;
    for (uint16_t i = 0; i < char_count; i++) {
        const struct src_addr_item_t *char_item = &g_addr_table[font_char_start_index + i];
        if (char_item->type != is_font_char) continue;
        for (uint8_t j = 0; j < char_num; j++) {
            if (!char_found[j] && char_item->char_code == char_codes[j]) {
                char_widths[j] = char_item->width;
                char_found[j] = 1;
                // 不break，允许同一编码多次出现
            }
        }
    }

    // 4. 统计总宽度
    uint16_t total_width = 0;
    for (uint8_t i = 0; i < char_num; i++) {
        if (char_found[i] && char_widths[i] > 0) {
            total_width += char_widths[i];
        } else {
            // 未找到字符，使用字体高度一半作为宽度兜底
            total_width += font_item.height / 2;
        }
    }

    src_log("字符串宽度计算完成: 字体=%s, 总宽度=%u\r\n", name, total_width);

    return (uint8_t)total_width;
}

/**
 * @brief 获取中文字符（UTF-8三字节）宽度
 * @param name 字体资源名称
 * @return 字符宽度（像素）
 */
uint8_t src_manager_get_cn_char_lenght(char *name){
    struct src_addr_item_t font_item;
    if (src_manager_find_and_read_by_name(name, is_font, &font_item) != 0) {
        return 0; // 未找到字体，直接返回0
    }
    // 先判断字体资源的下一个元素是否就是中文字符（is_font_char）
    uint32_t font_char_start_index = font_item.id;
    const struct src_addr_item_t *first_char_item = &g_addr_table[font_char_start_index];
    if (first_char_item->type == is_font_char) {
        return first_char_item->width;
    }
    // 如果不是，再遍历查找
    uint16_t char_count = font_item.char_count;
    for (uint16_t i = 0; i < char_count; i++) {
        const struct src_addr_item_t *char_item = &g_addr_table[font_char_start_index + i];
        if (char_item->type == is_font_char) {
            return char_item->width;
        }
    }
    // 如果没有找到，兜底返回字体高度一半
    return font_item.height / 2;
}


static struct src_addr_item_t addr_table_find_name(char *name, enum is_type_e type)
{
	struct src_addr_item_t empty_item = {0};
	if(type != is_audio && type != is_font && type != is_image) return empty_item;

	// 使用按需读取函数查找资源
	if (src_manager_find_and_read_by_name(name, type, &src_addr_table) == 0) {
		return src_addr_table; // 成功返回整个结构体
	}
	
	return empty_item; // 未找到返回空结构体
}

static struct src_addr_item_t addr_tanle_find_font_code(char *name)
{
	struct src_addr_item_t empty_item = {0};
	// 遍历资源地址表，查找类型为is_font_char的资源，名称完全匹配
	for(uint32_t i = 0; i < src_head.addr_table_item_count; i++){
		// 读取当前索引的地址表项
		if (src_manager_read_addr_table_item(i) != 0) {
			continue;
		}
		
		if(src_addr_table.type == is_font_char && strcmp(src_addr_table.name, name) == 0){
			return src_addr_table; // 找到则返回整个结构体
		}
	}
	return empty_item; // 未找到返回空结构体
}


// 使用静态2KB缓冲区，去掉行高选项，每次读取的行数贴着2KB
void src_manager_print_image_by_lines(uint16_t x, uint16_t y, tImage image, uint32_t addr)
{
	tImage image_origin = image;
	tImage image_show = {0};
	uint16_t pos_y = y;
	uint32_t read_addr = 0, read_len = 0;

	// 参数有效性检查
	if (image_origin.width == 0 || image_origin.height == 0)
	{
		src_log("[src_manager_print_image_by_lines] invalid image size: %ux%u\r\n", image_origin.width, image_origin.height);
		return;
	}

	// 计算 bpp 对应的字节数，默认至少按 2 字节处理以兼容 16bpp 资源
	uint8_t bytes_per_pixel = (image_origin.dataSize + 7u) / 8u;
	if (bytes_per_pixel == 0) bytes_per_pixel = 2;

	// 叠加数据区基址，addr 为资源在数据区内的偏移
	uint32_t real_addr = src_get_real_data_addr(addr);
	uint16_t start_page = real_addr / 256, offset = real_addr % 256;

	// 静态2KB缓冲区
	static uint8_t line_buffer[STATIC_LINE_BUF_SIZE];

	// 计算每次能读取的最大行数
	uint32_t bytes_per_line = (uint32_t)image_origin.width * (uint32_t)bytes_per_pixel;
	uint16_t max_lines_per_read = (bytes_per_line == 0) ? 1 : (STATIC_LINE_BUF_SIZE / bytes_per_line);
	if (max_lines_per_read == 0) max_lines_per_read = 1; // 至少一行

	for(uint16_t i = 0; i < image_origin.height; i += max_lines_per_read){
		// 计算本次要读取的行数
		uint16_t curr_line_height = ((i + max_lines_per_read) > image_origin.height) ? (image_origin.height - i) : max_lines_per_read;

		read_len = (uint32_t)curr_line_height * (uint32_t)image_origin.width * (uint32_t)bytes_per_pixel;
		read_addr = real_addr + (uint32_t)i * (uint32_t)image_origin.width * (uint32_t)bytes_per_pixel;

		// 计算起始页和页内偏移（仅用于日志/调试，不强依赖跨页能力）
		start_page = read_addr / 256;
		offset = read_addr % 256;

		// 从Flash读取数据到缓冲区
		flash_read_cross_pages(read_addr, read_len, line_buffer);

		// 如需处理字节序，可在此按 RGB565 交换字节
		if (bytes_per_pixel == 2)
		{
			swap_rgb565_bytes(line_buffer, read_len);
		}

		// 填充image_show结构体
		image_show.data = (const uint16_t *)line_buffer;
		image_show.width = image_origin.width;
		image_show.height = curr_line_height;
		image_show.dataSize = image_origin.dataSize;

		// 新增转换为UG_BMP结构体（修正为定义变量后赋值，避免只读左值错误）
		UG_BMP bmp_show = {
			.p = (const void *)line_buffer,
			.width = image_origin.width,
			.height = curr_line_height,
			.bpp = 16, // 假设为16bpp，如有需要可根据实际image_origin.dataSize调整
			.colors = 0 // 若无调色板可设为0
		};

		// 显示本段图像（兼容UGUI HAL库）
		UG_DrawBMP(x, pos_y, &bmp_show);

		// 更新y坐标
		pos_y += curr_line_height;
	}
}

/**
 * @brief 获取UTF-8编码的字符长度
 */
uint8_t _OLED_GetUTF8Len(char *string)
{
  if ((string[0] & 0x80) == 0x00)
  {
    return 1;
  }
  else if ((string[0] & 0xE0) == 0xC0)
  {
    return 2;
  }
  else if ((string[0] & 0xF0) == 0xE0)
  {
    return 3;
  }
  else if ((string[0] & 0xF8) == 0xF0)
  {
    return 4;
  }
  return 0;
}

uint8_t src_manager_set_font_fore_color(UG_COLOR color){
    fore_color  = color;
    return 1;
}
uint8_t src_manager_set_font_back_color(UG_COLOR color){
    back_color  = color;
    return 1;
} 

